import turtle

# (1)运动命令:
# 1 forward/fd(degree)  # 向前移动距离degree代表距离
# 2 backward/bd(degree)  # 向后移动距离degree代表距离
# 3 right(degree)  # 向右移动多少度
# 4 left(degree)  # 向左移动多少度
# 5 goto(x, y)  # 将画笔移动到坐标为x,y的位置
# 6 stamp()  # 复制当前图形
# 7 speed(speed)  # 画笔绘制的速度范围[0,10]整数
# 8 setheading/seth(angle)  # 方向（0度向右，90度向上，180度向左）

# (2)画笔控制命令:
# 1. pendown()  # 移动时绘制图形,缺省时也为绘制
# 2. penup()  # 移动时不绘制图形
# 3. pensize(width)  # 绘制图形时的宽度
# 4. color(colorstring)  # 绘制图形时的颜色
# 5. fillcolor(colorstring)  # 绘制图形的填充颜色
# 6. fill(Ture)
# 7. fill(false)


def basic_turtle():
    # turtle.setup(width, height, startx, starty) # setup设置窗体大小
    # width：窗体的宽度
    # height：窗体的高度
    # startx: 窗体距离屏幕边缘的左边像素距离
    # starty: 窗体距离屏幕上面边缘的像素距离
    # 其中，后两个参数是可选项，如果不填写该参数，窗口会默认显示在屏幕的正中间。
    turtle.setup(600, 500, 50, 10)
    # 绝对坐标：以屏幕中间为原点（0，0），形成四象限的坐标体系。

    # 使用turtle.goto(x, y)方法来让海龟沿着绝对坐标进行运动：
    turtle.goto(100, 100)
    turtle.goto(100, -100)
    turtle.goto(-100, -100)
    turtle.goto(-100, 100)
    turtle.goto(0, 0)

    # 海龟坐标：是以海龟的视角的坐标体系，分为四个方向：
    # turtle.fd(distance)  # 前进(屏幕右侧)
    # turtle.bk(distance)  # 后退(屏幕左侧)
    # turtle.rt(angle)  # 右转(屏幕下侧)
    # turtle.lt(angle)  # 左转(屏幕上侧)
    turtle.left(45)
    turtle.fd(100)
    turtle.right(135)
    turtle.fd(300)
    turtle.left(135)
    turtle.fd(150)

    # 绝对坐标体系下 有一个绝对角度体系
    # 使用turtle.seth(angle)方法改变海龟的朝向，但不运动

    # 海龟的角度坐标体系下，只分左转和右转两种情况。
    # 使用以下方法来改变它的角度：
    # turtle.left(angle)  # 向海龟左边改变运行方向
    # turtle.right(angle)  # 向海龟右边改变运行方向

    # RGB色彩体系：三种基础颜色：red green blue构成万物色。
    # RGB色彩体系中，每个基础颜色的取值范围是0-255的整数，或0-1的小数
    # 英文名称	     RGB整数值	        RGB小数值
    # white	        255, 255, 255	    1, 1, 1	            白色
    # yellow	    255, 255, 0	        1, 1, 0	            黄色
    # magenta	    255, 0, 255	        1, 0, 1	            洋红
    # cyan	        0, 255, 255	        0，1，1	            青色
    # blue	        0, 0, 255	        0，0，1	            蓝色
    # black	        0, 0, 0	            0，0，0	            黑色
    # purple	    160, 32, 240	    0.63, 0.13, 0.94	紫色
    # 使用turtle.colormode(mode)来调整海龟的颜色，默认采用RGB小数值，可以切换为整数值
    # mode 小数值模式： 1.0
    # mode 整数值模式： 255

    # 画笔控制:
    # 画笔操作后一直有效，一般成对使用
    # turtle.penup()  # turtle.pu()  抬起画笔，不再画线
    # turtle.pendown()  # turtle.pd() 落下画笔，继续画线
    # 画笔设置后一直有效，直到下次重新设置
    # turtle.pensize(width)  # turtle.width(width)  设置画笔的宽度
    # turtle.pencolor(color)  # color 为 色彩RGB值 设置画笔的颜色
    # color参数 有三种形式
    # 颜色字符串
    # turtle.pencolor('purple')  # 小写
    # RGB小数值
    # turtle.pencolor(0.63, 0.13, 0.94)  # 三个小数值
    # RGB数值元组
    # turtle.pencolor((0.63, 0.13, 0.94))  # 一个三元素元组

    # 运动控制函数:控制画笔的行进： 走直线 & 走曲线
    # 直线
    # turtle.fd(d)   d为参数行进距离   控制画笔向前走d长度的直线  d可以为负数，表示向后运动
    turtle.forward(10)
    # 曲线
    # turtle.circle(r, extent=None) 根据半径r绘制extent角度的弧形    r 默认圆心在画笔左端点距离r长度的地方  extent是绘制的角度，默认绘制完整的圆形
    turtle.circle(100)  # 在画笔的左侧（也就是上方）100距离的位置上然后以弧形来运动，没有设置extent参数，因此会绘制整个圆形
    turtle.circle(-100, 90)  # 圆心在画笔的右侧100距离（也就是下方）上，然后extent为90，因此绘制一个90度的弧形。

    # 方向控制函数
    # 控制h画笔面对的方向：绝对角度 & 画笔角度

    # 绝对角度转向函数
    # turtle.setheading(angle)# turtle.seth(angle)  改变画笔的面向的角度（ 初始方向是画布的正右方）  参数angle是绝对坐标系的角度
    # 画笔角度转向函数
    # turtle.left(angle)  # 向左转angle度
    # turtle.right(angle)  # 向右转angle度
    # 方向控制函数只改方向，但是不会动，运动由运动控制函数实现。

    turtle.right(135)
    turtle.forward(20)

    # 让我们先看一下turtle.stamp()的作用
    # 画笔颜色设为红色
    turtle.color("red")
    # 定义一个颜色列表
    color = ['blue', 'yellow', 'red', 'green', 'gray']
    num = 0
    while num < 5:
        # 当前位置拷贝一份箭头形状,也就是在当前的位置留下一个箭头的形状
        stamp_id = turtle.stamp()
        # 在这里我们为了识别方便改变一下画笔的颜色
        turtle.color(color[num])
        # 前进100像素
        turtle.fd(100)
        num += 1

    # 保存为eps矢量图
    turtle.getscreen()
    turtle.getcanvas().postscript(file='work.eps')

    # 删除拷贝的箭头形状(此处id最后一次复制的stamp_id)
    turtle.clearstamp(stamp_id)
    print(stamp_id)
    # 删除第一个拷贝的形状
    turtle.clearstamp(1)
    turtle.clearstamps(-1)  # 删除最后一个拷贝形状
    turtle.clearstamps()  # 删除全部拷贝形状
    turtle.clearstamps(0)  # 不删除
    # 一直撤销最后一个动作直到不可撤销
    while turtle.undobufferentries():
        # 撤销最后的一次动作
        turtle.undo()


def basic_attribute():
    # turtle.position() | pos()：返回(海龟)箭头当前位置坐标
    print(turtle.pos())

    # turtle.towards(x, y=None)：返回(海龟)箭头当前位置指向(x, y)位置连线的向量的角度
    # (取决于当前模式, “standard”/”world”默认方向向右(即东)逆时针开始“logo”模式默认方向向上(即北)顺时针开始)
    # 参数：x：x可以是一个number或者一个二维的数组或者一个turtle instence(海龟实例)
    # y：x是一个number, y就是一个number 否则y为None
    turtle.goto(20, 20)
    # 移动后，位置为(20,20),两个向量分别是(20,20)点到(0,0)点的向量和(20,20)点到箭头当前方向的向量
    angle = turtle.towards(0, 0)
    print("两向量角度:", angle)  # 225.0
    angle = turtle.towards((0, 0))
    print("两向量角度:", angle)  # 225.0
    turtle1 = turtle.Turtle()
    turtle1.setpos(0, 0)
    angle = turtle.towards(turtle1)
    print("两向量角度:", angle)  # 225.0
    turtle1 = turtle.Turtle()
    turtle1.setpos(0, 0)
    angle = turtle1.towards(turtle1)
    print("两向量角度:", angle)  # 0.0
    turtle2 = turtle.Turtle()
    turtle2.setpos(50, 50)
    angle = turtle1.towards(turtle2)
    print("两向量角度:", angle)  # 45.0

    # turtle.xcor()：返回箭头的x坐标；turtle.ycor()：返回箭头的y坐标；
    turtle.lt(50)
    turtle.fd(100)
    # 打印箭头当前坐标
    print(turtle.pos())  # (64.28,76.60)
    print(round(turtle.xcor(), 5))  # 保留5位读取x坐标 64.27876
    print(round(turtle.ycor(), 5))  # 保留5位读取y坐标 76.60444

    # turtle.heading()：返回当前(海龟)箭头方向角度
    print(turtle.heading())

    # turtle.distance(x, y=None)：返回当前(海龟)箭头坐标与坐标(x, y)间距离或者当前(海龟)箭头坐标与另一个(海龟)箭头坐标间距离
    turtle.home()
    print(turtle.distance(30, 40))  # 距离为50.0
    print(turtle.distance((30, 40)))  # 距离为50.0
    joe = turtle.Turtle()
    joe.setpos(30, 40)
    print(turtle.distance(joe))  # 距离为50.0


def basic_attribute1():
    screen = turtle.getscreen()
    # 设置海龟窗口标题
    screen.title("hello turtle")

    # 获取海龟绘图窗口高度(单位:像素)
    print(turtle.window_height())
    # 获取海龟绘图窗口宽度(单位：像素)
    print(turtle.window_width())

    # screen.bye() | turtle.bye()：关闭海龟图形窗口

    # screen.exitonclick() | turtle.exitonclick()：调用此方法后屏幕会保持，直到点击屏幕才会关闭海龟图形窗口
    # turtle.exitonclick()

    # screen.mainloop() | screen.done() | turtle.mainloop() | turtle.done()：启动循环事件，调用此方法后屏幕会保持，直到主动关闭当前窗口；想使用的话必须作为图形绘制程序的最后一条语句
    # turtle.mainloop()


def basic_attribute2():
    print(turtle.undobufferentries())
    # turtle.setundobuffer(size)：设置或者禁止撤销功能，size为None表示禁止撤销功能；否则设置多大，就可以通过调用undo()方法撤销多少次
    turtle.setundobuffer(42)
    while turtle.undobufferentries():  # 判断是否可撤销
        turtle.undo()  # 执行撤销操作

    # screen.bgcolor(*args)：设置或返回海龟屏幕TurtleScreen的背景色
    # args---一个颜色字符串或3个范围是0-colormode的数字或三个元组
    screen = turtle.getscreen()
    screen.bgcolor("orange")
    # 打印‘orange’
    print(screen.bgcolor())
    screen.bgcolor("#800080")
    print(screen.bgcolor())
    # screen.bgpic(picname=None)：设置/删除背景图片或返回当前的背景图片名
    # 参数
    # picname--- 一个gif的字符串名字或"nopic"字符串或None
    # git图片名：表示设置海龟屏幕TurtleScreen的背景图像
    # "nopic"：表示删除海龟屏幕TurtleScreen的背景图像
    # "None"：表示返回海龟屏幕TurtleScreen的背景图像的名称
    screen = turtle.getscreen()
    # 打印当前背景图像名，打印结果为'nopic'
    print(screen.bgpic())
    # 设置背景图像，h.gif需要提前放到该文件同级目录
    screen.bgpic("h.gif")
    # 打印当前背景图像名，打印结果为"h.gif"
    print(screen.bgpic())
    # screen.bgpic('nopic')
    # 打印当前背景图像名，打印结果为'nopic'
    # print(screen.bgpic())

    # 【注意：背景图片只能是gif格式，所以我们需要预先下载gif格式的照片，通过更改后缀的方式，并不能完成图片格式的更改】

    # screen.screensize(canvwidth=None, canvheight, bg=None)：如果没给出参数，则返回当前的画布大小(canvwidth, canvheight)否则表示调整画布的大小
    screen = turtle.getscreen()
    # 打印当前画布大小，结果为(400,300)
    print(screen.screensize())
    # 调整画布大小，变大后出现了滚动条，可通过滑动滑块查看画布隐藏的部分
    screen.screensize(2000, 1500)
    # 打印当前画布大小，结果为(2000,1500)
    print(screen.screensize())

    turtle.done()


if __name__ == '__main__':

    basic_turtle()

    # 属性方法
    basic_attribute()

    basic_attribute1()

    basic_attribute2()
